Encryption.generateSalt   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
c 0
b 0
f 0
nc 1
dl 0
loc 3
rs 10
nop 0
1
var assert = require('assert');
2
var sjcl = require('sjcl');
3
var KeyDerivation = require('./keyderivation');
4
var randomBytes = require('randombytes');
5
6
var Encryption = {
7
    defaultSaltLen: 10, /* can permit changes, no more than 512 bit (128 bytes) */
8
    tagLenBits: 128, /* can permit changes */
9
    ivLenBits: 128,  /* fixed */
10
    ivLenWords: 128 / 32
11
};
12
13
Encryption.generateSalt = function() {
14
    return randomBytes(this.defaultSaltLen);
15
};
16
17
Encryption.generateIV = function() {
18
    return randomBytes(this.ivLenBits / 8);
19
};
20
21
Encryption.encrypt = function(pt, pw, iterations) {
22
    var salt = this.generateSalt();
23
    var iv = this.generateIV();
24
25
    iterations = typeof iterations === 'undefined' ? KeyDerivation.defaultIterations : iterations;
26
    return this.encryptWithSaltAndIV(pt, pw, salt, iv, iterations);
27
};
28
29
Encryption.encryptWithSaltAndIV = function(pt, pw, saltBuf, iv, iterations) {
30
    assert(pt instanceof Buffer, 'pt must be provided as a buffer');
0 ignored issues
show
Bug introduced by
The variable Buffer seems to be never declared. If this is a global, consider adding a /** global: Buffer */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
31
    assert(pw instanceof Buffer, 'pw must be provided as a buffer');
32
    assert(iv instanceof Buffer, 'IV must be provided as a buffer');
33
    assert(saltBuf instanceof Buffer, 'saltBuff must be provided as a buffer');
34
    assert(iv.length === 16, 'IV must be exactly 16 bytes');
35
36
    var SL = (new Buffer(1));
37
    var S = saltBuf;
38
    var I = new Buffer(4);
39
    SL.writeUInt8(saltBuf.length);
40
    I.writeUInt32LE(iterations);
41
    var header = SL.toString('hex') + S.toString('hex') + I.toString('hex');
42
43
    var key = sjcl.codec.hex.toBits(KeyDerivation.compute(pw, saltBuf, iterations).toString('hex'));
44
    var ct_t = sjcl.mode.gcm.encrypt(
45
      new sjcl.cipher.aes(key),
46
      sjcl.codec.hex.toBits(pt.toString('hex')),
47
      sjcl.codec.hex.toBits(iv.toString('hex')),
48
      sjcl.codec.hex.toBits(header),
49
      this.tagLenBits
50
    );
51
52
    // iter || saltLen8 || salt || iv || tag || ct
53
    return new Buffer([header, iv.toString('hex'), sjcl.codec.hex.fromBits(ct_t)].join(''), 'hex');
54
};
55
56
Encryption.decrypt = function(ct, pw) {
57
    assert(ct instanceof Buffer, 'cipherText must be provided as a Buffer');
0 ignored issues
show
Bug introduced by
The variable Buffer seems to be never declared. If this is a global, consider adding a /** global: Buffer */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
58
    assert(pw instanceof Buffer, 'password must be provided as a Buffer');
59
    var copy = new Buffer(ct, 'hex');
60
    var c = 0;
61
62
    var saltLen = copy.readUInt8(c)      ; c += 1;
63
    var salt = copy.slice(1, c + saltLen); c += saltLen;
64
    var iterations = copy.readUInt32LE(c); c += 4;
65
    var header = copy.slice(0, c);
66
67
    var iv = copy.slice(c, 16 + c); c += 16;
68
    var ct_t = copy.slice(c);
69
70
    // SaltBuf is required for KeyDerivation. Convert to sjcl where required.
71
    var key = KeyDerivation.compute(pw, salt, iterations);
72
    var plainText = sjcl.mode.gcm.decrypt(
73
      new sjcl.cipher.aes(sjcl.codec.hex.toBits(key.toString('hex'))),
74
      sjcl.codec.hex.toBits(ct_t.toString('hex')),
75
      sjcl.codec.hex.toBits(iv.toString('hex')),
76
      sjcl.codec.hex.toBits(header.toString('hex')),
77
      this.tagLenBits
78
    );
79
    return new Buffer(sjcl.codec.hex.fromBits(plainText), 'hex');
80
};
81
82
module.exports = Encryption;
83